package com.joysuch.wwyt.util;

import com.google.common.base.Strings;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.Hashtable;

/**
 * 生成二维码
 */
public class QrCodeUtil {
    private static final String CHARSET = "utf-8";
    // 二维码尺寸
    private static final int QRCODE_SIZE = 600;
    // 用二维码生成新图片，新图片加高多少，比如加的字体大小为24，这里就设置成26
    private static final int FONT_SIZE_HEIGHT = 50;
    // 用二维码生成新图片，宽度
    private static final int BUFFEREDIMAGE_SIZE_WIDTH = QRCODE_SIZE;
    // 用二维码生成新图片，高度
    private static final int BUFFEREDIMAGE_SIZE_HEIGHT = QRCODE_SIZE + FONT_SIZE_HEIGHT;

    /**
     * 二维码生成BASE64，返给前端
     * @param code 二维码图值信息
     */
    public static void createQrFile(String code, String text, String outputFilePath) throws Exception {
        ByteArrayOutputStream outputStream = null;
        try {
            if (Strings.isNullOrEmpty(code)) {
                throw new IllegalArgumentException("二维码值为空");
            }

            Hashtable<EncodeHintType, Object> hints = new Hashtable<>(16);
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
            hints.put(EncodeHintType.MARGIN, 1);
            BitMatrix bitMatrix = new MultiFormatWriter().encode(code,
                    BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);

            outputStream = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(bitMatrix, "PNG", outputStream);

            ByteArrayInputStream in = new ByteArrayInputStream(outputStream.toByteArray());
            BufferedImage image = ImageIO.read(in);
            BufferedImage bufferedImage = addNote(image, new String((text).getBytes("UTF-8"), "UTF-8"));
            ImageIO.write(bufferedImage, "PNG", new File(outputFilePath));
        } finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }

    /**
     * 给二维码下方添加说明文字
     *
     * @param image 原二维码
     * @param note  说明文字
     * @return 带说明文字的二维码
     */
    public static BufferedImage addNote(BufferedImage image, String note) {
        Image src = image.getScaledInstance(QRCODE_SIZE, QRCODE_SIZE, Image.SCALE_DEFAULT);
        BufferedImage tag = new BufferedImage(BUFFEREDIMAGE_SIZE_WIDTH, BUFFEREDIMAGE_SIZE_HEIGHT, BufferedImage.TYPE_INT_RGB);
        //设置低栏白边
        Graphics g1 = tag.getGraphics();
        g1.fillRect(0, QRCODE_SIZE, QRCODE_SIZE, FONT_SIZE_HEIGHT);
        //设置文字
        Graphics2D g2 = tag.createGraphics();
        Font font = new Font("微软雅黑", Font.BOLD, 24);
        g2.setFont(font);
        g2.setColor(Color.BLACK);

        FontMetrics fm = g2.getFontMetrics(font);
        int ascent = fm.getAscent();
        int descent = fm.getDescent();
        int x = (QRCODE_SIZE - fm.stringWidth(note)) / 2;
        int y = (FONT_SIZE_HEIGHT - (ascent + descent)) / 2 + ascent;

        g2.drawString(note,x, QRCODE_SIZE + font.getSize());
        g1.drawImage(src, 0, 0, null);
        g1.dispose();
        g2.dispose();
        image = tag;
        image.flush();
        return image;
    }

    public static void main(String[] args) throws Exception {
        createQrFile("1", "二维码风险点二维码风险点 - 液氯仓库一液氯仓库一", "D:/qr.png");
    }
}

